package com.bofa.test.cases.base;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.ui.Select;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;

import com.bofa.manager.domain.UserLogin;
import com.bofa.test.cases.enums.Selector;

public class BOFASeleniumBase {
	static Logger logger = Logger.getLogger(BOFASeleniumBase.class.getName());
	public WebDriver webdriver;
	public static Properties baseProperties = null;
	public Properties uiProperties = null;
	
	static{
		baseProperties = new Properties();
		// This property file can be loaded from class path
		InputStream baseInputStream = BOFASeleniumBase.class.getClassLoader().getResourceAsStream("bofa-base-config.properties");
		try {
			baseProperties.load(baseInputStream);
		} catch (IOException e) {
			logger.error(""+ExceptionUtils.getStackTrace(e));
		}
	}
	
	@BeforeClass
	public void initialise() throws Exception {
		logger.error("InitialiseSeleniumDrivers BOFASeleniumBase.setUp()....");

		uiProperties = new Properties();
		// This property file need to be loaded from the project source
		uiProperties.load(new FileInputStream("config/bofa-gui.properties"));

		webdriver = getWebdriver();
		String timeoutString = baseProperties.getProperty("timeout.seconds");
		long timeout = Long.parseLong(timeoutString);
		webdriver.manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS);
		webdriver.manage().window().maximize();
		logger.error("InitialiseSeleniumDrivers BOFASeleniumBase.setUp() DONE.");
	}

	public void navigateToPage() {
		webdriver.get(getBaseUrl() + "/V4/");
	}

	public WebDriver getWebdriver() throws Exception {
		String browser = getBrowser();
		WebDriver webdriver = null;
		if (browser.contentEquals("firefox")) {
			FirefoxProfile firefoxProfile = new FirefoxProfile();
			firefoxProfile.setAssumeUntrustedCertificateIssuer(false);
			webdriver = new FirefoxDriver(firefoxProfile);
		} else if (browser.contentEquals("internetExplorer")) {
			webdriver = new InternetExplorerDriver();
		} else if (browser.contentEquals("chrome")) {
			System.setProperty("webdriver.chrome.driver",
					"InputTestData/chromedriver.exe");
			webdriver = new ChromeDriver();
		}
		return webdriver;
	}

	public String getBrowser() {
		String baseUrl = baseProperties.getProperty("browser");
		return baseUrl;
	}

	public String getBaseUrl() {
		String baseUrl = baseProperties.getProperty("guru99.bank.baseUrl");
		return baseUrl;
	}

	protected void click(String expression, Selector selector) {
		By element = null;
		switch (selector) {
		case ID:
			element = By.id(expression);
			break;
		case CSS:
			element = By.cssSelector(expression);
			break;
		case XPATH:
			element = By.xpath(expression);
			break;
		case NAME:
			element = By.name(expression);
			break;
		case LINKTEXT:
			element = By.linkText(expression);
			break;
		}
		webdriver.findElement(element).click();
	}

	protected void sendKeys(String expression, String input, Selector selector) {
		By element = null;
		switch (selector) {
		case ID:
			element = By.id(expression);
			break;
		case CSS:
			element = By.cssSelector(expression);
			break;
		case XPATH:
			element = By.xpath(expression);
			break;
		case NAME:
			element = By.name(expression);
			break;
		default:
			break;
		}
		webdriver.findElement(element).clear();
		webdriver.findElement(element).sendKeys(input);
	}
	protected String getText(String expression, Selector selector) {
		By element = null;
		switch (selector) {
		case ID:
			element = By.id(expression);
			break;
		case CSS:
			element = By.cssSelector(expression);
			break;
		case XPATH:
			element = By.xpath(expression);
			break;
		case NAME:
			element = By.name(expression);
			break;
		default:
			break;
		}
		String customerId = webdriver.findElement(element).getText();
		return customerId;
	}
	
	public List<String> getElementsFromDropDown(String expression,
			Selector selector) {
		List<String> dropdownTexts = new ArrayList<String>();
		By element = null;
		switch (selector) {
		case ID:
			element = By.id(expression);
			break;
		case CSS:
			element = By.cssSelector(expression);
			break;
		case XPATH:
			element = By.xpath(expression);
			break;
		case NAME:
			element = By.name(expression);
			break;
		default:
			break;
		}

		Select s = new Select(webdriver.findElement(element));
		List<WebElement> options = s.getOptions();
		for (WebElement webElement : options) {
			dropdownTexts.add(webElement.getText());
		}
		return dropdownTexts;
	}
	public void selctFrmDropdown(String expression,Selector selector,String input){
		By element = null;
		switch (selector) {
		case ID:
			element = By.id(expression);
			break;
		case CSS:
			element = By.cssSelector(expression);
			break;
		case XPATH:
			element = By.xpath(expression);
			break;
		case NAME:
			element = By.name(expression);
			break;
		default:
			break;
		}
		
		new Select(webdriver.findElement(element)).selectByVisibleText(input);
	}

	public void setFirstElementFromDropDown(String expression, Selector selector) {
		List<String> elementsFromDropDown = getElementsFromDropDown(expression,
				selector);
		String firstElement = "";
		if (CollectionUtils.isNotEmpty(elementsFromDropDown)) {
			firstElement = elementsFromDropDown.get(0);
		}

		By element = null;
		switch (selector) {
		case ID:
			element = By.id(expression);
			break;
		case CSS:
			element = By.cssSelector(expression);
			break;
		case XPATH:
			element = By.xpath(expression);
			break;
		case NAME:
			element = By.name(expression);
			break;
		default:
			break;
		}
		new Select(webdriver.findElement(element))
				.selectByVisibleText(firstElement);
	}
	
	public void selectInputRadio(String expression, Selector selector, String internalValueToSelect) {
		
		By element = null;
		switch (selector) {
		case ID:
			element = By.id(expression);
			break;
		case CSS:
			element = By.cssSelector(expression);
			break;
		case XPATH:
			element = By.xpath(expression);
			break;
		case NAME:
			element = By.name(expression);
			break;
		default:
			break;
		}

		List<WebElement> radios = webdriver.findElements(element);
		boolean isOptionFound = false;
		for (WebElement webElement : radios) {
			String attribute = webElement.getAttribute("value");
			if(internalValueToSelect.equals(attribute)){
				webElement.click();
				isOptionFound = true;
			}
		}
		
        if (!isOptionFound) {
            logger.error("Radio Option not found.");
        } 
    }

	// alert check
	public boolean isAlertPresent() {
		try {
			webdriver.switchTo().alert();
			return true;
		} catch (Exception e) {
			logger.info("No alert present");
			return false;
		}
	}
	
	public String getAlerText(){
		String alertMessage = webdriver.switchTo().alert().getText();
		webdriver.switchTo().alert().accept();
		webdriver.switchTo().defaultContent();
		return alertMessage;
	}
	
	@AfterClass
	public void teardown() {
		logger.info("Tearing down with quit");
		webdriver.quit();
	}
	
	public boolean login() {
		String loggedInUser = uiProperties.getProperty("bofa.secure.login.user");
		String loggedInPassword = uiProperties.getProperty("bofa.secure.login.password");
		
		UserLogin userLogin = new UserLogin(loggedInUser, loggedInPassword);
		
		boolean isSucessfull = false;
		navigateToPage();
		sendKeys(uiProperties.getProperty("bofa.login.text.username"), userLogin.getUsername(), Selector.NAME);
		sendKeys(uiProperties.getProperty("bofa.login.text.password"), userLogin.getPassword(), Selector.NAME);
		click(uiProperties.getProperty("bofa.login.button.login"), Selector.NAME);

		if (!isAlertPresent()) {
			logger.info("Login Successful!");
			isSucessfull = true;
		}
		return isSucessfull;
	}
	
	public int randInt(){
		int min = 1999999; 
		int max = 9999999;
		Random rand = new Random();
		// nextInt is normally exclusive of the top value,
	    // so add 1 to make it inclusive
	    int randomNum = rand.nextInt((max - min) + 1) + min;

	    return randomNum;
	}
	
	public String getRandomEmail(){
		String emailFormat = "test%s@gmail.com";
		int randomNum = randInt();
		String email = String.format(emailFormat, randomNum);
	    return email;
	}
	
	/**
	 * Pause for X milliseconds.
	 * 
	 * @param iTimeInMillis
	 */
	public void pause(final int iTimeInMillis) {
		try {
			Thread.sleep(iTimeInMillis);
		} catch (InterruptedException ex) {
			logger.error(ex.getMessage());
		}
	}
}
